package com.lyw.utils;

import com.lyw.factory.TimerTaskFactory;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 获取坐标工具
 */
public class PositionUtil {

  public static volatile int[] monster_position = {-1, -1};

  private static final boolean[] shutdown = {false, false};

  // 技能框信息
  private static Rectangle skill_box;
  private static Rectangle character_box;
  private static Rectangle monster_box;
  private static final int SKILL_WIDTH = 216;
  private static final int SKILL_HEIGHT = 61;
  private static final int SKILL_X = 299;
  private static final int SKILL_Y = 533;
  // 技能坐标
  private static final int[][] SKILL_POSITION = {
          {10, 4}, {41, 4}, {72, 4}, {103, 4}, {124, 4}, {155, 4}, {186, 4},
          {10, 35}, {41, 35}, {72, 35}, {103, 35}, {124, 35}, {155, 35}, {186, 35}
  };
  // 可释放技能颜色
  private static final int[] SKILL_COLOR1 = {0, 255, 0};
  private static final int[] SKILL_COLOR2 = {102, 102, 102};
  // 所有技能能否释放的状态
  public static final ConcurrentHashMap<Integer, Boolean> SKILL_STATUS = new ConcurrentHashMap<>(20);
  // 技能优先级跟 -》 技能坐标 每个下标对应
  public static final List<Integer> SKILL_PRIORITY = Arrays.asList(
          KeyEvent.VK_Q, KeyEvent.VK_W, KeyEvent.VK_E, KeyEvent.VK_R, KeyEvent.VK_V, KeyEvent.VK_Y, KeyEvent.VK_T,
          KeyEvent.VK_A, KeyEvent.VK_S, KeyEvent.VK_D, KeyEvent.VK_F, KeyEvent.VK_G, KeyEvent.VK_H, KeyEvent.VK_7
  );

  // 怪物阈值
  public static final int MONSTER_WIDTH_THRESHOLD = 50;
  public static final int MONSTER_HEIGHT_THRESHOLD = 22;

  // 材料阈值
  public static final int MATERIAL_WIDTH_THRESHOLD = 80;
  public static final int MATERIAL_HEIGHT_THRESHOLD = 56;

  private static final int[] characterPosition = {-1, -1};
  private static final int[][] doorPosition = {{800, 600}};

  static {
    // 技能初始化
    SKILL_STATUS.put(KeyEvent.VK_Q, true);
    SKILL_STATUS.put(KeyEvent.VK_W, true);
    SKILL_STATUS.put(KeyEvent.VK_E, true);
    SKILL_STATUS.put(KeyEvent.VK_R, true);
    SKILL_STATUS.put(KeyEvent.VK_V, true);
    SKILL_STATUS.put(KeyEvent.VK_Y, true);
    SKILL_STATUS.put(KeyEvent.VK_T, true);
    SKILL_STATUS.put(KeyEvent.VK_A, true);
    SKILL_STATUS.put(KeyEvent.VK_S, true);
    SKILL_STATUS.put(KeyEvent.VK_D, true);
    SKILL_STATUS.put(KeyEvent.VK_F, true);
    SKILL_STATUS.put(KeyEvent.VK_G, true);
    SKILL_STATUS.put(KeyEvent.VK_H, true);
    SKILL_STATUS.put(KeyEvent.VK_7, true);
  }

  private PositionUtil() {
  }

  public static void enableGetCharacterPositionInfo(TimerTaskFactory taskFactory,
                                                    Robot robot,
                                                    Rectangle rectangle,
                                                    int[] colors) {

    taskFactory.execute(() -> {
      final int[] bufInfo = {30, 120, 80, 130};
      int[] startInterval = {-1, -1}, position, finalRgb;
      int i, length;

      position = PositionUtil.getPosition(robot, rectangle, colors);
      characterPosition[0] = position[0];
      characterPosition[1] = position[1];

      while (true) {
        long start = System.currentTimeMillis();
        startInterval[0] = characterPosition[0] - bufInfo[0];
        startInterval[1] = characterPosition[1] - bufInfo[1];
        rectangle.setBounds(startInterval[0], startInterval[1], bufInfo[2], bufInfo[3]);
        finalRgb = robot.createScreenCapture(rectangle)
                .getRGB(0, 0, bufInfo[2], bufInfo[3], null, 0, bufInfo[2]);
        System.out.println(System.currentTimeMillis() - start);
        start = System.currentTimeMillis();
        length = finalRgb.length;
        for (i = 0; i < length; i += 20) {
          if (((finalRgb[i] >> 16) & 0xff) == colors[0]
                  && ((finalRgb[i] >> 8) & 0xff) == colors[1]
                  && (finalRgb[i] & 0xff) == colors[2]) {
            characterPosition[0] = (startInterval[0] + i % bufInfo[2]);
            characterPosition[1] = (startInterval[1] + i / bufInfo[2]) + 93;
//                            System.out.println(StringUtil.format("({}, {})", characterPosition[0], characterPosition[1]));
            break;
          }
        }

        if (i == finalRgb.length) {
          rectangle.setBounds((int) rectangle.getLocation().getX(), (int) rectangle.getLocation().getY(), 800, 600);
          position = PositionUtil.getPosition(robot, rectangle, colors);
          characterPosition[0] = position[0];
          characterPosition[1] = position[1];
        }

        if (shutdown[0]) {
          shutdown[0] = false;
          break;
        }
        System.out.println(System.currentTimeMillis() - start);
      }
    });
  }

  public static void disEnabledGetCharacterPositionInfo() {

    if (!shutdown[0]) {
      shutdown[0] = true;
    }
  }

  /**
   * 准备开启技能扫描功能
   */
  public static void prepareEnableCharacterScan(Rectangle rectangle) {

  }

  /**
   * 根据上一次的位置快速定位人物坐标
   */
  public static int[] getCharacterByLastTimePosition(
          int[] characterPosition,
          Robot robot,
          Rectangle rectangle,
          int[] colors
  ) {

    final int[] bufInfo = {30, 120, 80, 130};
    int[] startInterval = {-1, -1}, finalRgb;
    int i, length;

    startInterval[0] = characterPosition[0] - bufInfo[0];
    startInterval[1] = characterPosition[1] - bufInfo[1];
    character_box = new Rectangle(startInterval[0], startInterval[1], bufInfo[2], bufInfo[3]);
    finalRgb = robot.createScreenCapture(character_box)
            .getRGB(0, 0, bufInfo[2], bufInfo[3], null, 0, bufInfo[2]);
    length = finalRgb.length;
    for (i = 0; i < length; i += 20) {
      if (((finalRgb[i] >> 16) & 0xff) == colors[0]
              && ((finalRgb[i] >> 8) & 0xff) == colors[1]
              && (finalRgb[i] & 0xff) == colors[2]) {
        characterPosition[0] = (startInterval[0] + i % bufInfo[2]);
        characterPosition[1] = (startInterval[1] + i / bufInfo[2]) + 93;
        return new int[]{characterPosition[0], characterPosition[1]};
      }
    }

    return getPosition(robot, rectangle, colors);
  }

  public static int[] getPosition(Robot robot, Rectangle rectangle, int[] colors) {
    Point location = rectangle.getLocation();

    BufferedImage imageInfo = robot.createScreenCapture(rectangle);
    int[] rgb = imageInfo.getRGB(0, 0, 800, 600, null, 0, 800);
    int x = -1;
    int y = -1;

    for (int i = 0; i < rgb.length; i += 2) {
      if (((rgb[i] >> 16) & 0xff) == colors[0]
              && ((rgb[i] >> 8) & 0xff) == colors[1]
              && (rgb[i] & 0xff) == colors[2]) {
        x = (int) (location.getX() + i % 800);
        y = (int) (location.getY() + i / 800) + 91;
        break;
      }
    }
    return new int[]{x, y};
  }

  /**
   * 获取怪物坐标
   */
  public static int[][] getMonsterAndCharacterPosition(Robot robot) {
    BufferedImage screenCapture = robot.createScreenCapture(monster_box);
    int x = -1, y = -1;
    int[][] res = {{-1, -1}, {800, 600}};
    boolean whetherFind = false;
    int width = screenCapture.getWidth();
    int height = screenCapture.getHeight();
    for (int i = 0; i < width; i += MONSTER_WIDTH_THRESHOLD) {
      for (int j = 0; j < height; j += MONSTER_HEIGHT_THRESHOLD) {
        int rgb = screenCapture.getRGB(i, j);
        if (((rgb >> 16) & 0xff) == 255
                && ((rgb >> 8) & 0xff) == 255
                && (rgb & 0xff) == 255) {
          if (res[1][0] > x) {
            res[1][0] = (int) (i + monster_box.getX());
            res[1][1] = (int) (j + monster_box.getY() + 50);
          }
        }

        if (!whetherFind && ((rgb >> 16) & 0xff) == 9
                && ((rgb >> 8) & 0xff) == 251
                && (rgb & 0xff) == 251) {
          res[0][0] = (int) (i + monster_box.getX());
          res[0][1] = (int) (j + monster_box.getY() + 90);
          whetherFind = true;
        }
      }
    }
    System.out.println(res[0][0] + ", " + res[0][1] + " --- " + res[1][0] + ", " + res[1][1]);
    return res;
  }
  public static void getMonsterPosition1(Robot robot) {
    while (true) {
      long start = System.currentTimeMillis();
      BufferedImage screenCapture = robot.createScreenCapture(monster_box);
      int x = -1, y = -1;
      int width = screenCapture.getWidth();
      int height = screenCapture.getHeight();
      for (int i = 0; i < width; i += MONSTER_WIDTH_THRESHOLD) {
        for (int j = 0; j < height; j += MONSTER_HEIGHT_THRESHOLD) {
          int rgb = screenCapture.getRGB(i, j);
          if (((rgb >> 16) & 0xff) == 255
                  && ((rgb >> 8) & 0xff) == 255
                  && (rgb & 0xff) == 255) {
            x = i;
            y = j + 50;
            System.out.println(x + ", " + y);
          }
        }
      }
      System.out.println(System.currentTimeMillis() - start);
    }
  }
  /**
   * 获取材料坐标
   */
  public static List<int[]> getMaterialPosition(Robot robot, Rectangle rectangle) {
    BufferedImage screenCapture = robot.createScreenCapture(rectangle);
    List<int[]> res = new ArrayList<>();
    int width = screenCapture.getWidth();
    int height = screenCapture.getHeight();
    for (int i = 0; i < width; i += MATERIAL_WIDTH_THRESHOLD) {
      for (int j = 0; j < height; j += MATERIAL_HEIGHT_THRESHOLD) {
        int rgb = screenCapture.getRGB(i, j);
        if (((rgb >> 16) & 0xff) == 241
                && ((rgb >> 8) & 0xff) == 145
                && (rgb & 0xff) == 73) {
          res.add(new int[]{i, j});
        }
      }
    }

    return res;
  }
  public static void prepareGetMonsterArea(Rectangle rectangle) {

    monster_box = new Rectangle((int) rectangle.getX(), (int) rectangle.getY() + 123, (int) rectangle.getWidth(), (int) rectangle.getHeight() - 123);
  }
}
